

import copy

import numpy as np

from analyse.kline_handler.enum import RiseAndFallType
from analyse.kline_handler.rise_and_fall_handler import RiseAndFallHandler
from analyse.trend_handler.kline_handler.fall import FallKlineHandler
from analyse.trend_handler.kline_handler.flat import FlatKlineHandler
from analyse.trend_handler.kline_handler.rise import RiseKlineHandler
from analyse.trend_handler.volume_handler.kline import KlineVolumeHandler
from utils.kline import calc_actual_chg, get_klines_range, get_range_volume_mean


class Trend:
    def __init__(self, props):
        self.original_klines = props.get('klines')
        klines=copy.deepcopy(self.original_klines)
        self.klines = copy.deepcopy(self.original_klines)
        self.trends=[]
        self.trend=None
        #全局均量
        self.global_avg_volume=get_range_volume_mean(klines,0,len(klines))
        #大于均量的k线
        self.greater_than_klines=[kline for kline in klines if kline["volume"]>self.global_avg_volume]
        #小于均量的k线
        self.less_than_klines=[kline for kline in klines if kline["volume"]<=self.global_avg_volume]
        #大于均量的k线的数量
        self.greater_than_len=len(self.greater_than_klines)
        #小于均量的k线的数量
        self.less_than_len=len(self.less_than_klines)
        #大于均量的k线的均量
        self.greater_avg_volume=np.mean([kline["volume"] for kline in self.greater_than_klines])
        #小于均量的k线的均量
        self.less_avg_volume=np.mean([kline["volume"] for kline in self.less_than_klines])
        #小于的数量/大于的数量之比
        if self.greater_than_len == 0:
            self.ratio_less_greater_len = 0  # 或者 float('inf') 根据业务需求决定
        else:
            self.ratio_less_greater_len = self.less_than_len / self.greater_than_len
        #大于均量的k线的均量/小于均量的k线的均量之比
        self.ratio_greater_less_avg_volume=self.greater_avg_volume/self.less_avg_volume

    def push_trend(self):
        self.trends.append(self.trend)
        self.trend=None
        
    def iterate(self):
        
        riseKlineHandler=RiseKlineHandler()
        fallKlineHandler=FallKlineHandler()
        flatKlineHandler=FlatKlineHandler()

        klineVolumeHandler=KlineVolumeHandler()
        
        for index, kline in enumerate(self.klines):
            rise_and_fall_handler=RiseAndFallHandler()
            new_kline=rise_and_fall_handler.handle(kline)
            kline_type=rise_and_fall_handler.get_kline_type(new_kline)
      
            preClose=new_kline["preClose"]
            close=new_kline["close"]
            rise_and_fall_type=kline_type['rise_and_fall_type']
           
          
            def init_trend():
                self.trend={
                    "preClose":preClose,
                    "close":close,
                    "startIndex":index,
                    "endIndex":index,
                    "startTime":new_kline["time"],
                    "endTime":new_kline["time"],
                    "type":rise_and_fall_type,
                    "actualChg":calc_actual_chg(preClose,close)
                }
            
            if index==0:
                init_trend()
            else:
                if self.trend==None:
                    init_trend()
              
                props={
                    "parent":self,
                    "kline":new_kline,
                    "klineType":kline_type,
                    "index":index,
                    "klines":self.klines,
                    "init_trend":init_trend,
                }
                if rise_and_fall_type==RiseAndFallType.上涨.value:
                    riseKlineHandler.analyse(props)
                elif rise_and_fall_type==RiseAndFallType.下跌.value:
                   fallKlineHandler.analyse(props)
                else:
                    flatKlineHandler.analyse(props)

                klineVolumeHandler.analyse(props)
                    
        self.push_trend()
        print(self.trends)
        
        #         self.recognition()
                
        #     else:
        #         if self.trend==None:
        #             self.trend=self.trends.pop()
        #         if self.trend["type"]==rise_and_fall_type:
        #             self.trend["endIndex"]=index
        #             self.trend["endTime"]=new_kline["time"]
        #             self.trend["close"]=new_kline["close"]
        #             self.trend["actualChg"]=calc_actual_chg(self.trend['preClose'],close)
        #         elif self.trend["type"]!=type:
        #             self.push_trend()
        #             init_trend()
        #         self.recognition()
        # self.push_trend()
        # print(self.trends)
        

    # def recognition(self):
    #     print(self.trend)
    #     if abs(self.trend["actualChg"])>30:
    #         self.push_trend()
            


            

           
            
